ЗАНЯТТЯ № 2
Написання простих програм на мові асемблер
для мікроконтролера AT90S2313
1. Написати підпрограму додавання вмісту двох 8-розрядних комірок SRAM, що знаходяться за адресами Addr_1 = 90Н, Addr_2 = 91Н. Якщо результат не рівний нулю, помістити його в комірку пам’яті SRAM з адресою Addr_1, в протилежному випадку вивести результат в порт B.
; Заголовочний файл
.include <2313def.inc>
; Адреса першого числа
.equ Addr_1 = 0x90
; Адреса другого числа
.equ Addr_2 = 0x91
; Початок сегменту коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi r16, 0xDF
out SPL, r16 ; Ініціалізація стеку
rcall PP_1 ; Виклик підпрограми додавання
Wait:
rjmp Wait ; Вічний цикл
PP_1: ; Початок підпрограми додавання
lds r0, Addr_1 ; Завантажити в регістр r0 перше число
lds r1, Addr_2 ; Завантажити в регістр r1 друге число
add r0, r1 ; Додати два числа, результат занести в r0
breq L1 ; Якщо результат = 0, перейти на мітку L1
sts Addr_1, r0 ; Інакше зберегти результат за адресою Addr_1
rjmp L2 ; Перейти на мітку L2
L1: out PORTB, r0 ; Вивести результат в порт В
L2:
ret ; Повернення з підпрограми
2. Написати підпрограму переводу безнакового цілого числа розташованого в комірці пам’яті SRAM з адресою Addr = 80Н, в двійково-десятковий код. Результат розташувати в регістрах загального призначення.
; Заголовичний файл
.include <2313def.inc>
; Адреса числа, яке потрібно перевести в двійково-десятковий код
.equ Addr = 0x80
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
; Регістри сотень, десятків та одиниць
.def LCD_100 = r20
.def LCD_10 = r21
.def LCD_1 = r22
; Сегмент коду
.cseg
; Початкова адреса 0
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND ; RAMEND = 0xDF (див. файл 2313def.inc)
out SPL, temp1 ; Ініціалізація стеку
ldi temp1, 125 ; Нехай потрібно перевести число 125
sts Addr, temp1 ; Зберегти 125 за адресою Addr
rcall Bin_to_Dec ; Виклик підпрограми переводу
Wait:
rjmp Wait ; Вічний цикл
Bin_to_Dec:
lds temp1, Addr ; Занести число для переводу в temp1
ldi LCD_100, -1 ; Присвоїти LCD_100 = -1
B2: inc LCD_100 ; LCD_100 = LCD_100 + 1
subi temp1, 100 ; temp1 = temp1 - 100
brsh B2 ; Якщо temp1 >= 0 перейти на В2
ldi LCD_10, 100 ; Відновити temp1
add temp1, LCD_10 ; temp1 = temp1 + 100
ldi LCD_10, -1 ; Присвоїти LCD_10 = -1
B3: inc LCD_10 ; LCD_10 = LCD_10 + 1
subi temp1, 10 ; temp1 = temp1 - 10
brsh B3 ; Якщо temp1 >= 0 перейти на В3
ldi temp2, 10 ; Відновити temp1
add temp1, temp2 ; temp1 = temp1 + 10
mov LCD_1, temp1 ; Занести в LCD_1 кількість одиниць
ret ; Повернення з підпрограми
3. Написати підпрограму переводу двійково-десяткового числа розташованого в комірці пам’яті SRAM з адресою Addr = С0Н в двійковий код. Результат розташувати в регістрі загального призначення.
; Заголовочний файл
.include <2313def.inc>
; Адреса числа, яке потрібно перевести в двійковий код
.equ Addr = 0xC0
; Робочі регістри
.def temp1 = r16
.def temp2 = r17
; Регістр результату
.def result = r18
; Сегмент коду
.cseg
; Початкова адреса
.org 0
; Вектор скиду
RESET:
ldi temp1, RAMEND
out SPL, temp1 ; Ініціалізація стеку
ldi temp1, 0b01010111
sts Addr, temp1 ; Занести в Addr число 57 (2-10)
rcall BCD_BIN ; Виклик підпрограми переводу 2-10->2
Wait:
rjmp Wait ; Вічний цикл
; Підпрограма переводу з 2-10 коду в двійковий
BCD_BIN:
ldi result, 0 ; Обнулити регістр результату (result = 0)
lds temp1, Addr ; Завантажити в temp1 вміст Addr (temp1 = 0b01010111)
mov result, temp1 ; Переслати 0b01010111 в result
andi result, 0b00001111 ; Виділити одиниці: result = 0b00000111
swap temp1 ; Поміняти місцями тетради: temp1 = 0b01110101
andi temp1, 0b00001111 ; Виділити десятки: result = 0b00000101
ldi temp2, 10 ; temp2 = 10
L1:
subi temp1, 1 ; tem...